include( 'cl_interface_scheme.lua' )
include( 'animation.lua')


function GetSystemButton(type, width, height, onClick, parent)

	if parent == nil then
		return nil
	end

	local button = vgui.Create("DSysButton", parent)
	button:SetType(type)	
	button:SetSize(width, height)
   if onClick then
	button.DoClick = onClick
end
	
	button.Paint = function() 

		local endX = button:GetWide();

		surface.SetDrawColor(PANEL_LIGHT.r, PANEL_LIGHT.g, PANEL_LIGHT.b, 255) 	
		surface.DrawRect(0,0, button:GetWide(), button:GetTall()) 

		local factor = (255 / button:GetTall())

		if not button:GetDisabled() then
		local scale = 1;
		if button.Hovered then
			scale = 0.5
		end
		if button:GetSelected()  then

		surface.SetDrawColor(0,0,0, 255) 	
		surface.DrawRect( 1, 1 , endX, button:GetTall()) 
			
		else
			
			for i=1, button:GetTall() do

				local grad = (i * factor)
				local base = (255 - grad);
				if button:IsDown() or button:GetSelected() then
					base = grad;		
				end
				surface.SetDrawColor(33 + scale * base * .132, 33 +scale * base * .142, 33 +scale * base * .142, 255) 	
				surface.DrawLine( 1, i , endX, i) 
				end
			end
		end
		surface.DrawOutlinedRect( 0, 0, button:GetWide(), button:GetTall()) 	
		
		surface.SetDrawColor(PANEL_HIGHLIGHT.r * .65, PANEL_HIGHLIGHT.g* .65, PANEL_HIGHLIGHT.b* .65, 255) 
		surface.DrawLine( 2, 2, 2, button:GetTall() - 2) 
		surface.DrawLine( 2, 2, button:GetWide() - 2, 2) 
			
		surface.SetDrawColor(PANEL_BLACK.r * 0.15, PANEL_BLACK.g* 0.15, PANEL_BLACK.b* 0.15, 255) 
		surface.DrawLine( button:GetWide() - 1, 1, button:GetWide() - 1, button:GetTall() - 1) 
		surface.DrawLine( 1, button:GetTall() - 1, button:GetWide() - 1, button:GetTall() - 1) 
	end

	return button
end


function GetButton(label, onClick, parent)

	if parent == nil then
		return nil
	end

	local button = vgui.Create("DButton", parent)
	button:SetText(label)

	button.Paint = function() 

	local endX = button:GetWide();

	surface.SetDrawColor(PANEL_LIGHT.r, PANEL_LIGHT.g, PANEL_LIGHT.b, 255) 	
	surface.DrawRect(0,0, button:GetWide(), button:GetTall()) 

	local factor = (255 / button:GetTall())

	if not button:GetDisabled() then
	local scale = 1;
	if button.Hovered then
		scale = 0.5
	end
	if button:GetSelected()  then

	surface.SetDrawColor(0,0,0, 255) 	
	surface.DrawRect( 1, 1 , endX, button:GetTall()) 
		
	else
		
		for i=1, button:GetTall() do

			local grad = (i * factor)
			local base = (255 - grad);
			if button:IsDown() or button:GetSelected() then
				base = grad;		
			end
			surface.SetDrawColor(33 + scale * base * .132, 33 +scale * base * .142, 33 +scale * base * .142, 255) 	
			surface.DrawLine( 1, i , endX, i) 
		end
	end
end
	surface.DrawOutlinedRect( 0, 0, button:GetWide(), button:GetTall()) 	
	
	surface.SetDrawColor(PANEL_HIGHLIGHT.r * .65, PANEL_HIGHLIGHT.g* .65, PANEL_HIGHLIGHT.b* .65, 255) 
	surface.DrawLine( 2, 2, 2, button:GetTall() - 2) 
	surface.DrawLine( 2, 2, button:GetWide() - 2, 2) 
		
	surface.SetDrawColor(PANEL_BLACK.r * 0.15, PANEL_BLACK.g* 0.15, PANEL_BLACK.b* 0.15, 255) 
	surface.DrawLine( button:GetWide() - 1, 1, button:GetWide() - 1, button:GetTall() - 1) 
	surface.DrawLine( 1, button:GetTall() - 1, button:GetWide() - 1, button:GetTall() - 1) 
	end

	button.DoClick = onClick
	return button
end

function GetButtonEx(label, onClick, width,height, parent)
	local button = vgui.Create("DButton", parent) 
	button:SetText(label) 
	button:SetSize(width,height)

button.Paint = function() 

	local endX = button:GetWide();

	surface.SetDrawColor(PANEL_LIGHT.r, PANEL_LIGHT.g, PANEL_LIGHT.b, 255) 	
	surface.DrawRect(0,0, button:GetWide(), button:GetTall()) 

	local factor = (255 / button:GetTall())
	if not button:GetDisabled() then
	local scale = 1;
	if button.Hovered then
		scale = 0.5
	end
	if button:GetSelected()  then
scale = 0.25
		end
	for i=1, button:GetTall() do
		local grad = (i * factor)
		local base = (255 - grad);
		if button:IsDown() then
			base = grad;		
		end
		surface.SetDrawColor(33 + scale * base * .132, 33 +base * .132, 33 +base * .132, 255) 	
		surface.DrawLine( 1, i , endX, i) 
	end
	end

	surface.DrawOutlinedRect( 0, 0, button:GetWide(), button:GetTall()) 	
	
	surface.SetDrawColor(PANEL_HIGHLIGHT.r * .65, PANEL_HIGHLIGHT.g* .65, PANEL_HIGHLIGHT.b* .65, 255) 
	surface.DrawLine( 2, 2, 2, button:GetTall() - 2) 
	surface.DrawLine( 2, 2, button:GetWide() - 2, 2) 
		
	surface.SetDrawColor(PANEL_BLACK.r * 0.15, PANEL_BLACK.g* 0.15, PANEL_BLACK.b* 0.15, 255) 
	surface.DrawLine( button:GetWide() - 1, 1, button:GetWide() - 1, button:GetTall() - 1) 
	surface.DrawLine( 1, button:GetTall() - 1, button:GetWide() - 1, button:GetTall() - 1) 
	end

	button.DoClick = onClick
	return button
end

function GetTextLabel(text, parent)

	if parent == nil then
		return nil
	end

	local label = vgui.Create("DLabel", parent) 
	label:SetText(text) 
	label:SetFont("DefaultSmall")
	//label:SetTextColor(Color(0,0,0)) 
	label:SizeToContents()
	return label
end

function GetTextLabelEx(text, fontName, parent)

	if parent == nil then
		return nil
	end

	local label = vgui.Create("DLabel", parent) 
	label:SetText(text) 
		  if(fontName == nil) then
			  label:SetFont("DefaultSmall")
		  else
	label:SetFont(fontName)
		  end
	label:SizeToContents()
	return label
end


MMSlider = { };
MMSlider.LeftNav = nil;
MMSlider.RightNav = nil;
MMSlider.Label = nil;
MMSlider.Display = nil;
MMSlider.DisplayBG = nil;
MMSlider.ValueDisp = nil;
MMSlider.Min = 0;
MMSlider.Max = 100;
MMSlider.Value = 50;
MMSlider.OnValueChanged = function(val) end

function MMSlider:Init( ) 

	local label = vgui.Create("DLabel", self)
	label:SetPos(3,0)
	label:SetFont("DefaultSmall")
	label:SetSize(((2 * self:GetWide()) / 3) - 3, self:GetTall() / 2)
	label:SetText("")
	self.Label = label

	local valueDisp = vgui.Create("DLabel", self)
	valueDisp:SetFont("DefaultSmall")
	valueDisp:SetSize(self:GetWide() - (3 + label:GetWide()), self:GetTall() / 2)
	valueDisp:SetPos( self:GetWide() - (valueDisp:GetWide() + 3),0)
	valueDisp:SetText(string.format("%G", self.Value))
	self.ValueDisp = valueDisp

	local leftNav = GetSystemButton("left", math.min(20, self:GetWide() / 3), self:GetTall() / 2, nil, self)
	leftNav:SetPos( 0,self:GetTall() / 2) 
	leftNav.Velocity = 0.0
	leftNav.WasDown = false
	leftNav.Think = function ()
		if leftNav:IsDown() then
			leftNav.WasDown = true
			leftNav.Velocity = math.min(leftNav.Velocity + 0.035, (self.Max - self.Min) * 0.2)
			self.Value = math.max(self.Min, math.min(self.Max, self.Value - leftNav.Velocity))
		else
			if leftNav.WasDown == true then
				leftNav.WasDown = false
				if self.OnValueChanged then
					self:OnValueChanged(self.Value)
				end				
			end
			leftNav.Velocity = 0.0
		end
	end

	self.LeftNav = leftNav

	local rightNav = GetSystemButton("right", math.min(20, self:GetWide() / 3), self:GetTall() / 2, nil, self)
	rightNav:SetPos( self:GetWide() - rightNav:GetWide(), self:GetTall() / 2)
	rightNav.Velocity = 0.0
	rightNav.WasDown = false
	rightNav.Think = function ()
		if rightNav:IsDown() then
			rightNav.WasDown = true
			rightNav.Velocity = math.min(rightNav.Velocity + 0.035, (self.Max - self.Min) * 0.2)
			self.Value = math.max(self.Min, math.min(self.Max, self.Value + rightNav.Velocity))

		else
			if rightNav.WasDown == true then
				rightNav.WasDown = false
				if self.OnValueChanged then
					self:OnValueChanged(self.Value)
				end
			end
			rightNav.Velocity = 0.0
		end
	end

	self.RightNav = rightNav

	local displayBG = vgui.Create("DPanel", self)
	displayBG:SetPos(math.min(20, self:GetWide() / 3), self:GetTall() / 2)
	displayBG:SetSize((self:GetWide() - (rightNav:GetWide() + leftNav:GetWide())), self:GetTall() / 2)
	displayBG.Paint = function() 
	surface.SetDrawColor(255, 255, 255, 25) 
	surface.DrawRect(0,0, displayBG:GetWide(), displayBG:GetTall()) 
	end
	self.DisplayBG = displayBG


	local perc = self.Value / (self.Max - self.Min)
	local display = vgui.Create("DPanel", self)
	display:SetPos(math.min(20, self:GetWide() / 3), (self:GetTall() / 2) + 1)
	display:SetSize((self:GetWide() - (rightNav:GetWide() + leftNav:GetWide())) * perc, (self:GetTall() / 2) - 2)
	display.Paint = function() 
	surface.SetDrawColor(200, 150, 0, 255) 
	surface.DrawRect(0,0, display:GetWide(), display:GetTall()) 
	end
	self.Display = display

end  

function MMSlider:Paint() 

	local perc = (self.Value - self.Min) / (self.Max - self.Min)
	if self.Display then
		self.Display:SetSize((self:GetWide() - (self.RightNav:GetWide() + self.LeftNav:GetWide())) * perc, (self:GetTall() / 2) - 2)
	end

	if self.ValueDisp then
		self.ValueDisp:SetText( string.format("%.1f",self.Value))
	end

end

function MMSlider:SetText(val) 
	if self.Label then
		self.Label:SetText(val)
	end
end

function MMSlider:PerformLayout( ) 

	if self.Label then
		self.Label:SetPos(3,0)
		self.Label:SetSize(((2 * self:GetWide()) / 3) - 3, self:GetTall() / 2)
	end

	if self.ValueDisp then
		self.ValueDisp:SetSize(self:GetWide() - (3 +  self.Label:GetWide()), self:GetTall() / 2)
		self.ValueDisp:SetPos( self:GetWide() - (self.ValueDisp:GetWide() + 3),0)
	end
	
	if self.LeftNav then
		self.LeftNav:SetPos( 0,self:GetTall() / 2) 
		self.LeftNav:SetSize( math.min(20, self:GetWide() / 3), self:GetTall() / 2) 
	end

	if self.RightNav then
		self.RightNav:SetSize( math.min(20, self:GetWide() / 3), self:GetTall() / 2) 
		self.RightNav:SetPos( self:GetWide() - self.RightNav:GetWide(), self:GetTall() / 2)
	end

	if self.DisplayBG then 
		self.DisplayBG:SetPos(math.min(20, self:GetWide() / 3), self:GetTall() / 2)
		self.DisplayBG:SetSize((self:GetWide() - (self.RightNav:GetWide() + self.LeftNav:GetWide())), self:GetTall() / 2)
	end
	
	if self.Display then
		local perc = self.Value / (self.Max - self.Min)
		self.Display:SetSize((self:GetWide() - (self.RightNav:GetWide() + self.LeftNav:GetWide())) * perc, (self:GetTall() / 2) - 2)
		self.Display:SetPos(math.min(20, self:GetWide() / 3), (self:GetTall() / 2) + 1)
	end
end  

function MMSlider:SetMin(val) 
	if val > self.Max then
		self.Min = self.Max
		self.Max = val
	else
		self.Min = val
	end
end

function MMSlider:SetMax(val) 
	if val < self.Min then
		self.Max = self.Min
		self.Min = val
	else
		self.Max = val
	end
end

function MMSlider:SetValue(val)
	if val >= self.Min and val <= self.Max then
		self.Value = val
	end
end

vgui.Register( "DMMSlider" , MMSlider , "DPanel" ); 

function GetNumberSlider(text, min, max, value, onChangeFunc, parent)

	if parent == nil then
		print("ERROR", parent)
		return nil
	end

	local slider = vgui.Create( "DMMSlider", parent ) 
	slider:SetText( text ) 
	slider:SetMin( min )
	slider:SetMax( max )
	slider.OnValueChanged = onChangeFunc
	slider:SetValue(value)
	return slider

end

///////////////////////////////////////////////////

function GetSeperator(xStart,yStart,xEnd,yEnd, parent)

	if parent == nil then
		print("ERROR", parent)
		return nil
	end

	local seperate = vgui.Create( "DPanel", parent ) 
	seperate:SetParent(parent)
	seperate:SetPos(xStart, yStart);

	
	seperate.xEnd = xEnd;
	seperate.yEnd = yEnd;
	seperate:SetSize(xEnd + 11, yEnd + 11);
	seperate.Paint= function()
	
		local xD = seperate.xEnd
		local yD = seperate.yEnd

		surface.SetDrawColor(PANEL_DARK)
		surface.DrawLine( 1, 1, xD + 1, yD + 1)
		surface.SetDrawColor(SEPERATE_LIGHT)
		surface.DrawLine( 0, 0, xD, yD)
	end 
	return seperate

end

function GetImageButton(imageName, width, height, onClick, parent)

	if parent == nil then
		return nil
	end

	local button = vgui.Create("DImageButton", parent)
	button:SetSize(width, height)
	button:SetMaterial(imageName)
	button.DoClick = onClick

	button.Paint = function() 

		local endX = button:GetWide();

		surface.SetDrawColor(PANEL_LIGHT.r, PANEL_LIGHT.g, PANEL_LIGHT.b, 255) 	
		surface.DrawRect(0,0, button:GetWide(), button:GetTall()) 

		local factor = (255 / button:GetTall())

		if not button:GetDisabled() then
		local scale = 1;
		if button.Hovered then
			scale = 0.5
		end
		if button:GetSelected()  then

		surface.SetDrawColor(0,0,0, 255) 	
		surface.DrawRect( 1, 1 , endX, button:GetTall()) 
			
		else
			
			for i=1, button:GetTall() do

				local grad = (i * factor)
				local base = (255 - grad);
				if button:IsDown() or button:GetSelected() then
					base = grad;		
				end
				surface.SetDrawColor(33 + scale * base * .132, 33 +scale * base * .142, 33 +scale * base * .142, 255) 	
				surface.DrawLine( 1, i , endX, i) 
				end
			end
		end
		surface.DrawOutlinedRect( 0, 0, button:GetWide(), button:GetTall()) 	
		
		surface.SetDrawColor(PANEL_HIGHLIGHT.r * .65, PANEL_HIGHLIGHT.g* .65, PANEL_HIGHLIGHT.b* .65, 255) 
		surface.DrawLine( 2, 2, 2, button:GetTall() - 2) 
		surface.DrawLine( 2, 2, button:GetWide() - 2, 2) 
			
		surface.SetDrawColor(PANEL_BLACK.r * 0.15, PANEL_BLACK.g* 0.15, PANEL_BLACK.b* 0.15, 255) 
		surface.DrawLine( button:GetWide() - 1, 1, button:GetWide() - 1, button:GetTall() - 1) 
		surface.DrawLine( 1, button:GetTall() - 1, button:GetWide() - 1, button:GetTall() - 1) 
	end

	return button
end

function GetPanel(x,y,width,height,parent)

	if parent == nil then
		print("Error",parent);
		return nil
	end

	local panel = vgui.Create( "DPanel", parent ) 
	panel:SetPos(x,y)
	panel:SetSize(width,height)
	panel.Paint = function()
	surface.SetDrawColor(PANEL_BASE)
	surface.DrawRect( 0, 0, panel:GetWide(), panel:GetTall() )
	end 

	return panel
end

function GetPanelEx(x,y,width,height,color, parent)

	if parent == nil then
		print("Error",parent);
		return nil
	end

	local panel = vgui.Create( "DPanel", parent ) 
	panel:SetPos(x,y)
	panel:SetSize(width,height)
	panel.Paint = function()
	surface.SetDrawColor(color)
	surface.DrawRect( 0, 0, panel:GetWide(), panel:GetTall() )
	end 

	return panel
end

MMPREVIEWICON = { };  
MMPREVIEWICON.PreviewProp = nil
MMPREVIEWICON.PreviewEnabled = false

function MMPREVIEWICON:EnablePreview(val)
	self.PreviewEnabled = val
end

function MMPREVIEWICON:SetPreviewProp(prop)
	self.PreviewProp = prop
end

function MMPREVIEWICON:OnCursorEntered( ) 

	if self.PreviewProp != nil then
			
		if self.PreviewEnabled == true then
			self.PreviewProp:SetModel(self.ModelPathname)
			self.PreviewProp:SetNoDraw(false)
			self.PreviewProp:SetPos(LocalPlayer():EyePos() + (LocalPlayer():GetAimVector() * 100))
		else
			self.PreviewProp:SetNoDraw(true)
		end
	end
end  

function MMPREVIEWICON:Think()
	if self.PreviewProp != nil and self.PreviewEnabled == true then
			self.PreviewProp:SetAngles(Angle(0,CurTime() * 50.0,0))
	end
end

function MMPREVIEWICON:OnCursorExited( )  

	if self.PreviewProp != nil then
		self.PreviewProp:SetNoDraw(true)
	end

end  

vgui.Register( "MMPreviewIcon" , MMPREVIEWICON , "SpawnIcon" ); 

///////////////////////////////////////////////////////


MMDropMenu = { };
MMDropMenu.Items = {};
MMDropMenu.MenuButton = nil;
MMDropMenu.MenuList = nil;
MMDropMenu.CurrentValue = nil;

function MMDropMenu:ShowMenu( )

	if self.MenuList then
		self.MenuList:Close()
		self.MenuList = nil
		return
	end

	if self.Items then
		local itemCount = #self.Items
		local itemTall = 20

		if itemCount > 0 then

			self.MenuList = vgui.Create( "DFrame" ) 
			
			local i = 0
			local menuX, menuY = self.MenuButton:LocalToScreen()
			local height = math.min( 0.5 * (ScrH() - (ScrH() - menuY)), itemCount * itemTall)

			self.MenuList:SetPos( menuX, menuY -  height) 
			self.MenuList:SetSize( self:GetWide(),height)

			self.MenuList:SetVisible( true ) 
			self.MenuList:SetDraggable( false) 
			self.MenuList:ShowCloseButton( false) 
			self.MenuList:MakePopup()

			local menuPanelList = vgui.Create("DPanelList", self.MenuList)
			menuPanelList:SetPos(0,0)
			menuPanelList:SetSize(self.MenuList:GetWide(), self.MenuList:GetTall())
			menuPanelList:SetPadding(1)
			menuPanelList:SetSpacing(1)
			menuPanelList:EnableHorizontal(false)
			menuPanelList:EnableVerticalScrollbar(true)

			for _, item in pairs(self.Items) do

				local itemButton = nil
				local itemFunc = nil

				if item.Func then

					itemFunc = function()
						self.CurrentValue = item.Label
						self.MenuButton:SetText(self.CurrentValue)
											
						item:Func()
						self.MenuList:Close()
						self.MenuList = nil
					end
				else

					itemFunc = function()
					end
				end

				itemButton = GetButtonEx(item.Label, itemFunc, self:GetWide(),itemTall, menuPanelList)
				itemButton:SetPos(0, i * itemButton:GetTall())			  
				itemButton.Paint = function()

					if itemButton.Hovered then
						surface.SetDrawColor(DROP_MENU_HIGHLIGHT.r , DROP_MENU_HIGHLIGHT.g, DROP_MENU_HIGHLIGHT.b, 255) 	
					elseif not item.Func then
						surface.SetDrawColor(DROP_MENU_SPACER.r, DROP_MENU_SPACER.g, DROP_MENU_SPACER.b, 255) 	
					else
						surface.SetDrawColor(DROP_MENU_BACK.r, DROP_MENU_BACK.g, DROP_MENU_BACK.b, 255) 	
					end				
					surface.DrawRect(0,0, itemButton:GetWide(), itemButton:GetTall()) 
					surface.SetDrawColor(DROP_MENU_SPERATE.r, DROP_MENU_SPERATE.g, DROP_MENU_SPERATE.b, 255) 	
					surface.DrawLine( 1, itemButton:GetTall() - 1, itemButton:GetWide() - 1, itemButton:GetTall() - 1) 
				end
				
				menuPanelList:AddItem(itemButton)
				i = i + 1
			end
		end
	end
end

function MMDropMenu:SetText( val )
	if self.MenuButton and val then
		self.MenuButton:SetText(val)
	end
end

function MMDropMenu:Init( ) 

	self.MenuButton = GetButtonEx("", function() self:ShowMenu() end, self:GetWide(),self:GetTall(), self)
	self.MenuButton:SetPos(0,0);
	self:SetPaintBackground(false)
end  

function MMDropMenu:SetItems(items) 

	if items and #items > 0 then
		self.Items = items
			for _, item in pairs(self.Items) do
			if item.Func then
				self.CurrentValue = item.Label
				self.MenuButton:SetText(self.CurrentValue)
				return
			end
		end
		self.MenuButton:SetText("")
	else
		self.Items = nil
	end
end  

function MMDropMenu:PerformLayout( ) 

	if self.MenuButton then
		self.MenuButton:SetPos(0,0);
		self.MenuButton:SetSize(self:GetWide(), self:GetTall())
	end
end  

vgui.Register( "DMMDropMenu" , MMDropMenu , "DPanel" ); 

function GetDropMenu(itemList, parent)

	if parent == nil then
		print("ERROR", parent)
		return nil
	end

	local slider = vgui.Create( "DMMDropMenu", parent ) 
	slider:SetItems(itemList)
	return slider

end

///////////////////////////////////////////////////

//TODO: DESPERATE TIDY UP
MMDAnimSequenceItem = { };
MMDAnimSequenceItem.Items = {};
MMDAnimSequenceItem.AnimationButton = nil;
MMDAnimSequenceItem.EffectButton = nil;
MMDAnimSequenceItem.TargetButton = nil;
MMDAnimSequenceItem.UpButton = nil;
MMDAnimSequenceItem.DownButton = nil;
MMDAnimSequenceItem.DeleteButton = nil;

MMDAnimSequenceItem.CurrentAnimation = nil;
MMDAnimSequenceItem.CurrentEffect = nil;
MMDAnimSequenceItem.CurrentTarget = nil;
MMDAnimSequenceItem.OnDataChanged = nil;


function MMDAnimSequenceItem:UserCallback( ) 
	if self.OnDataChanged then
		self:OnDataChanged()
	end

	print("user call:"," ",
self.CurrentAnimation, " ",
self.CurrentEffect ," ",
self.CurrentTarget );

end

function MMDAnimSequenceItem:Init( ) 

	local animationList = {}
	local effectList = {}
	local targetsList = {}

	for animName, animCode in pairs(animations) do
		if animCode == "" then
			table.insert(animationList, {Label = animName})
		else
			table.insert(animationList, {Label = animName, Func = function() self.CurrentAnimation = animName self:UserCallback() end})
		end
	end

	for effectName, effectCode in pairs(effects) do
		if effectCode == "" then
			table.insert(effectList, {Label = effectName})
		else
			table.insert(effectList, {Label = effectName, Func = function() self.CurrentEffect = effectName self:UserCallback() end})
		end
	end

	for targetsName, targetsCode in pairs(targets) do
		if targetsCode == "" then
			table.insert(targetsList, {Label = targetsName})
		else
			table.insert(targetsList, {Label = targetsName, Func = function() self.CurrentTarget = targetsName self:UserCallback() end})
		end
	end

	self.AnimationButton = GetDropMenu(animationList, self)
	self.EffectButton = GetDropMenu(effectList, self)
	self.TargetButton = GetDropMenu(targetsList, self)

	self.CurrentAnimation = self.AnimationButton.CurrentValue
	self.CurrentEffect	= self.EffectButton.CurrentValue
	self.CurrentTarget	= self.TargetButton.CurrentValue

	self.UpButton = GetSystemButton("up", 1,self:GetTall(), 
	function()
		local parentPanelList = self:GetParent():GetParent()
		local parentItems = parentPanelList:GetItems()
		for i=1, #parentItems do
			if parentItems[i] == self and i > 1 then
				local t = parentItems[i-1]
				parentItems[i-1] = parentItems[i]
				parentItems[i] = t
				parentPanelList:InvalidateLayout()
				self:UserCallback()
				break
			end
		end	
	end, self);

				
	self.DownButton = GetSystemButton("down", 1,self:GetTall(), 
	function()
		local parentPanelList = self:GetParent():GetParent()
		local parentItems = parentPanelList:GetItems()
		for i=1, #parentItems do
			if parentItems[i] == self and i < #parentItems then
				local t = parentItems[i+1]
				parentItems[i+1] = parentItems[i]
				parentItems[i] = t
				parentPanelList:InvalidateLayout()
				self:UserCallback()
				break
			end
		end	
	end, self);

	self.DeleteButton = GetSystemButton("close", 1,self:GetTall(), 
	function()
		local parentPanelList = self:GetParent():GetParent()
		local parentItems = parentPanelList:GetItems()
		for i=1, #parentItems do
			if parentItems[i] == self then
				table.remove(parentItems, i)
				parentPanelList:InvalidateLayout()
				self:UserCallback()
				break
			end
		end	
	end, self);

	self:PerformLayout()
	self:SetPaintBackground(false)
end  

function MMDAnimSequenceItem:InitalizeDropLists(animationLabel, effectLabel, targetLabel) 

	self.CurrentAnimation = self.AnimationButton.CurrentValue
	self.CurrentEffect	= self.EffectButton.CurrentValue
	self.CurrentTarget	= self.TargetButton.CurrentValue

end

function MMDAnimSequenceItem:PerformLayout( ) 

	local width = self:GetWide()

	if self.AnimationButton then
	self.AnimationButton:SetSize(width * 0.25, self:GetTall())
	self.AnimationButton:SetPos(0,0)
	end

	if self.EffectButton then
	self.EffectButton:SetSize(width * 0.25, self:GetTall())
	self.EffectButton:SetPos(width * 0.25,0)
	end

	if self.TargetButton then
	self.TargetButton:SetSize(width * 0.25, self:GetTall())
	self.TargetButton:SetPos(width * 0.5,0)
	end

	if self.UpButton then
	self.UpButton:SetSize(width * 0.0833, self:GetTall())
	self.UpButton:SetPos(width * 0.75,0)
	end

	if self.DownButton then
	self.DownButton:SetSize(width * 0.0833, self:GetTall())
	self.DownButton:SetPos(width * 0.833,0)
	end

	if self.DeleteButton then
	self.DeleteButton:SetSize(width * 0.0833, self:GetTall())
	self.DeleteButton:SetPos(width * 0.9166,0)
	end

end  

vgui.Register( "MMDAnimSequenceItem" , MMDAnimSequenceItem , "DPanel" ); 

function GetAnimationSequenceItem(parent)

	if parent == nil then
		print("ERROR", parent)
		return nil
	end

	local slider = vgui.Create( "MMDAnimSequenceItem", parent ) 
	return slider

end

///////////////////////////////////////////////////


///////////////////////////////////////////////////

//TODO: DESPERATE TIDY UP
MMDKeyFrame = { };
MMDKeyFrame.FaceButton = nil;
MMDKeyFrame.KeyColor = KEY_FRAME_IDLE
MMDKeyFrame.OnTrackerEnter = nil
MMDKeyFrame.OnTrackerExit = nil
MMDKeyFrame.OnTrackerFrame = nil
MMDKeyFrame.WasClicked = false
MMDKeyFrame.Image = false


MMDKeyFrame.IsCurrentlyHeld = false

function MMDKeyFrame:Init( ) 
	self:SetSize(10,10)
	self:SetPos(0,0)
	self.KeyColor = KEY_FRAME_IDLE

	self.Image = vgui.Create("DImage", self) 
	self.Image:SetImage( "gui/MMMatKeyframe" ) 
	self.Image:SetPos(0,0)

end  

function MMDKeyFrame:Paint() 
self.Image:SetImageColor(self.KeyColor)
//	surface.SetDrawColor(self.KeyColor,155) 	
	//surface.DrawRect(0,0, self:GetWide(), self:GetTall() - 2) 

end

function MMDKeyFrame:PerformLayout( ) 

self.Image:SetSize(math.min(self:GetWide(),self:GetTall()),math.min(self:GetWide(),self:GetTall()))
self.Image:SetPos(0,(self:GetTall() - self.Image:GetTall()) * 0.5)
end  

vgui.Register( "MMDKeyFrame" , MMDKeyFrame , "DPanel" ); 

function GetKeyFrame(parent)

	if parent == nil then
		print("ERROR", parent)
		return nil
	end

	local slider = vgui.Create( "MMDKeyFrame", parent ) 
	return slider

end

////////////////////////////////////////////////////////////////////


//TODO: DESPERATE TIDY UP
MMDKeyFrameBar = { };
MMDKeyFrameBar.FaceButton = nil;

MMDKeyFrameBar.AddButton = nil

MMDKeyFrameBar.IsCurrentlyHeld = false
MMDKeyFrameBar.OnLeftClickKeyframe = nil
MMDKeyFrameBar.OnAddKeyframe = nil
MMDKeyFrameBar.Keyframes = {}
MMDKeyFrameBar.Editable = true
MMDKeyFrameBar.MinTime = 0
MMDKeyFrameBar.MaxTime = 0
MMDKeyFrameBar.CurrentTime = 0
MMDKeyFrameBar.PLAYING = 1
MMDKeyFrameBar.STOPPED = 0
MMDKeyFrameBar.PAUSED = 2
MMDKeyFrameBar.State = MMDKeyFrameBar.STOPPED

MMDKeyFrameBar.OnSample = nil
MMDKeyFrameBar.OnSampleFinished = nil

function MMDKeyFrameBar:SetState(state)
	self.State = state
end

function MMDKeyFrameBar:SetModel(model)

	self.Keyframes = {}

	if model then
		for kMod, oMod in pairs(model) do

			oMod.Panel = self:CreateKeyframe(oMod)
			table.insert(self.Keyframes, oMod)		

		end
		table.sort(self.Keyframes, function(kfA,kfB) 
			return kfA.Percentage < kfB.Percentage
		end)
	end
end

function MMDKeyFrameBar:RemoveKeyframe(keyframe) 

	if keyframe then
		local newKeyframes = {}

		for kKey, oKey in pairs(self.Keyframes) do

			if keyframe != oKey then
				table.insert(newKeyframes, oKey)
			end
		end

		keyframe.Panel:Remove()
		self.Keyframes = newKeyframes

		table.sort(self.Keyframes, function(kfA,kfB) 
			return kfA.Percentage < kfB.Percentage
		end)
	end
end

function MMDKeyFrameBar:CreateKeyframe(model) 

	local keyframe = vgui.Create( "MMDKeyFrame", self ) 
	
	keyframe:SetSize(15, self:GetTall())
keyframe:PerformLayout()

	keyframe.OnMousePressed = function(panel,mousecode) 
	
		if self.Editable == false then
			return 
		end

		if mousecode == MOUSE_LEFT then
			//When we have finisehd moving a keyframe, we want
			//to sort the keyframes table so that playback evaluation
			//can happen more efficently
			if keyframe.IsCurrentlyHeld then
				table.sort(self.Keyframes, function(kfA,kfB) 
					return kfA.Percentage < kfB.Percentage
				end)

				keyframe.IsCurrentlyHeld  = false
				if keyframe.WasClicked == false then
					keyframe.KeyColor = KEY_FRAME_IDLE
				end
				keyframe.WasClicked = false
			else
				if keyframe.KeyColor == KEY_FRAME_SELECTED or keyframe.KeyColor == KEY_FRAME_MOVING then
					keyframe.WasClicked = true
				end
				keyframe.KeyColor = KEY_FRAME_MOVING
				keyframe.IsCurrentlyHeld = true
				//self.OnLeftClickKeyframe(model)
			end
		elseif mousecode == MOUSE_RIGHT then
			if self.OnLeftClickKeyframe	then
		
				keyframe.KeyColor = KEY_FRAME_SELECTED
				self.OnLeftClickKeyframe(model)
			end
		end
	end
			 
	keyframe.Think = function()
	
		if self.Editable == false then
			return 
		end

		if keyframe.IsCurrentlyHeld then

			local x,y = keyframe:GetPos()
			local cx,cy = self:CursorPos()

			local lowerConstraint,_ = self:GetPos()
			lowerConstraint = lowerConstraint - 17
			local upperConstraint = self:GetWide() + lowerConstraint - self.AddButton:GetWide() - 12
			local tryPos = (cx - keyframe:GetWide() / 2)

			local finalPos = math.max(lowerConstraint, math.min(tryPos , upperConstraint ))
			keyframe:SetPos(finalPos,y)
			
			model.Percentage = finalPos / (upperConstraint - lowerConstraint)
				
		end
	end
	self:PerformLayout()
	return keyframe
end

function MMDKeyFrameBar:Init( ) 

	local callAddKeyframe = function() 
		if self.OnAddKeyframe then
			local keyframeModel = self.OnAddKeyframe()
			keyframeModel.Panel = self:CreateKeyframe(keyframeModel) 
			table.insert(self.Keyframes, keyframeModel)		
			table.sort(self.Keyframes, 
			function(kfA,kfB) 
				return kfA.Percentage < kfB.Percentage
			end)
			
		end
	end
	self.AddButton = GetButtonEx("+", callAddKeyframe, 20,20, self)
	self:PerformLayout()
end  

function MMDKeyFrameBar:Paint() 

	surface.SetDrawColor(KEY_FRAME_BAR_STIPEB) 	
	surface.DrawRect(0,0, self:GetWide(), self:GetTall()) 

	for i = -self:GetTall(), self:GetWide() do

		if i % 15 == 0 then
			
			surface.SetDrawColor(KEY_FRAME_BAR_STIPEA) 	
			surface.DrawLine(i + self:GetTall(), 0, i, self:GetTall())
			surface.DrawLine(i + 1 + self:GetTall(), 0, 1 + i, self:GetTall())
			surface.DrawLine(i + 2 + self:GetTall(), 0, 2 + i, self:GetTall())
			surface.DrawLine(i + 3 + self:GetTall(), 0, 3 + i, self:GetTall())
			surface.DrawLine(i + 4 + self:GetTall(), 0, 4 + i, self:GetTall())
			surface.DrawLine(i + 5 + self:GetTall(), 0, 5 + i, self:GetTall())
			surface.DrawLine(i + 6 + self:GetTall(), 0, 6 + i, self:GetTall())
		end
	end

	local lowerConstraint,_ = self:GetPos()
	lowerConstraint = lowerConstraint - 17
	local upperConstraint = self:GetWide() + lowerConstraint - 12
	if self.AddButton then
upperConstraint = upperConstraint -self.AddButton:GetWide() 
	end

	local percentage = self.CurrentTime / (self.MaxTime - self.MinTime)

	local x = lowerConstraint + ((upperConstraint - lowerConstraint) * percentage)

	if self.State != MMDKeyFrameBar.STOPPED then
		surface.SetDrawColor(121,143,40, 255) 	
		surface.DrawLine(x-2, 0, x-2, self:GetTall())
		surface.DrawLine(x+2, 0, x+2, self:GetTall())
		surface.SetDrawColor(213,240,240, 255) 	
		surface.DrawLine(x, 0, x, self:GetTall())
	end

	surface.SetDrawColor(PANEL_DARK) 	
	surface.DrawLine(0,0, 0, self:GetTall()) 
	surface.DrawLine(self:GetWide(),0, self:GetWide(), self:GetTall()) 
	surface.DrawLine(0,0, self:GetWide(), 0) 
	surface.DrawLine(0,self:GetTall() - 1, self:GetWide(), self:GetTall() - 1) 

end

function MMDKeyFrameBar:DoRewind( ) 
	self.CurrentTime = self.CurrentTime - 0.025 * (self.MaxTime - self.MinTime)
	self.CurrentTime = math.max(self.MinTime, math.min(self.MaxTime,self.CurrentTime))
end

function MMDKeyFrameBar:DoFastForward( ) 
	self.CurrentTime = self.CurrentTime + 0.025 * (self.MaxTime - self.MinTime)
	self.CurrentTime = math.max(self.MinTime, math.min(self.MaxTime,self.CurrentTime))
end
	

function MMDKeyFrameBar:Think( ) 

//	self:NextThink(CurTime() + 250)		


	//PLAYING
	if self.State == MMDKeyFrameBar.PLAYING then
		if self.CurrentTime > self.MaxTime then

			if self.OnSampleFinished then
				self.OnSampleFinished()
			end

			self.CurrentTime = self.MinTime
		else
			self.CurrentTime = self.CurrentTime + FrameTime()
		end
		
		self:Sample(self.CurrentTime)
	elseif self.State == MMDKeyFrameBar.STOPPED then

		self.CurrentTime = 0.0

	elseif self.State == MMDKeyFrameBar.PAUSED then

		if self.CurrentTime > self.MaxTime then
			self.CurrentTime  = self.MaxTime
		elseif self.CurrentTime < self.MinTime then
			self.CurrentTime  = self.MinTime 
		end
		self:Sample(self.CurrentTime)
		
	end

end

function MMDKeyFrameBar:Sample(time) 

	if not self.Keyframes or #self.Keyframes == 0 or not self.OnSample then
		return
	end

	if #self.Keyframes == 1 then

		self.OnSample(0.0, self.Keyframes[1], self.Keyframes[1])
		return
	end
		

	if time >= self.MinTime and time <= self.MaxTime then
		local duration = (self.MaxTime - self.MinTime)
		if duration <= 0 then
			return
		end

		local percentage = time / (self.MaxTime - self.MinTime)
		//print("____________")
		for i=1, #self.Keyframes do

	
			if i != #self.Keyframes then
				if percentage >= self.Keyframes[i].Percentage and percentage <= self.Keyframes[i+1].Percentage then
					//In between keyframe pairs 
					self.OnSample(percentage, self.Keyframes[i],self.Keyframes[i+1])
					return
				elseif percentage <= self.Keyframes[i].Percentage then
					//Before first keyframe so sample it fully
					self.OnSample(self.Keyframes[1].Percentage / 2.0, self.Keyframes[1],self.Keyframes[1])
					return
				end
			else
				//Beyond last keyframe so just sample it fully
				self.OnSample(self.Keyframes[#self.Keyframes].Percentage + (1.0 - self.Keyframes[#self.Keyframes].Percentage) * 0.5, self.Keyframes[#self.Keyframes],self.Keyframes[#self.Keyframes])
				return
			end
		end

		print("somthing screwed up!")
		
	end
end

function MMDKeyFrameBar:PerformLayout( ) 

	if self.AddButton then
		self.AddButton:SetSize(20,self:GetTall())
		self.AddButton:SetPos(self:GetWide() - self.AddButton:GetWide(), 0)
	end

	
	local lowerConstraint,_ = self:GetPos()
	lowerConstraint = lowerConstraint - 17
	local upperConstraint = self:GetWide()  + lowerConstraint - 12
	if self.AddButton then
		upperConstraint = upperConstraint - self.AddButton:GetWide() 
	end

	for kMod, oMod in pairs(self.Keyframes) do

		if oMod.Panel then
			oMod.Panel:SetPos(oMod.Percentage * upperConstraint, 0)
		end
	end
	
	for kKey, oKey in pairs(self.Keyframes) do
		oKey.Panel:SetSize(15, self:GetTall())
		oKey.Panel:PerformLayout()
	end

end  

function MMDKeyFrameBar:SetTimeLimits(minTime, maxTime)
	self.MinTime = minTime
	self.MaxTime = maxTime
end

function MMDKeyFrameBar:SetEditable(val)
	if val == false then
		
		self.Editable = false
		
		if self.AddButton then
			self.AddButton:Remove()
			self.AddButton = nil
		end

	else
		self.Editable = true
	end
end

vgui.Register( "MMDKeyFrameBar" , MMDKeyFrameBar , "DPanel" ); 

function GetKeyFrameBar(parent, model, minTime, maxTime)

	if parent == nil then
		print("ERROR", parent)
		return nil
	end

	local slider = vgui.Create( "MMDKeyFrameBar", parent ) 
	slider:SetModel(model)
	slider:SetTimeLimits(minTime, maxTime)

	return slider

end

function GetKeyFrameBarEx(parent, model, minTime, maxTime, editable)

	if parent == nil then
		print("ERROR", parent)
		return nil
	end

	local slider = vgui.Create( "MMDKeyFrameBar", parent ) 
	slider:SetEditable(editable)
	slider:SetModel(model)
	slider:SetTimeLimits(minTime, maxTime)

	return slider

end